机器学习-CoreML入门 结合ARKit


ARKit:

iOS11引入的全新的框架,允许开发者轻松地为 iPhone 和 iPad 创建无与伦比的增强现实体验。通过将虚拟对象和虚拟信息同用户周围的环境相互融合,ARKit 使得应 用跳出屏幕的限制,让它们能够以全新的方式与现实世界进行交互。

  • 所谓的增强现实 (Augmented Reality, AR),指的是向设备摄像头产生的实时动态视图中,添加 2D 或者 3D 元素,然后用某种方法让这些元素看起来就处于现实世界当中,所产生的一种用户体验。ARKit 提供设备动作追踪、相机场景捕获和高级场景处理,并让AR元素的展示变得极为便利,从而大大简化了建立 AR用户体验的工作难度。

  • ARSession类:
    这是一个单例, 是ARKit的核心类,用于控制设备摄像头,处理传感器数据,对捕获的图像进行分析等

  • ARSessionConfiguration类:
    跟踪设备 向的 个基本配置, 在运行时,需要指定AR运行的配置

  • ARWorldTrackingSessionConfiguration类:
    配置跟踪设备的方向和位置,以及检测设备摄像头所看到的现实世界的表面

  • ARSCNView类:
    用来增强相机通过 3D SceneKit 所捕捉到的内容并展示 AR 效果的一个 view

  • ARSKView类:
    用来增强相机通过 2D SpriteKit 所捕捉到的内容并展示AR 效果的一个 view

  • ARAnchor类:
    真实世界的位置和方向,用于在一个AR场景中放置一个物体

  • ARPlaneAnchor类:
    在一个AR Session会话中检测一个真实世界中平面的位置和方向的相关信息

  • ARHitTestResult类:
    在一个AR Session会话中通过检测相机视图中的一个点来获取真实世界中表面的相关信息

  • ARFrame类:
    捕获一个视频图像和位置追踪信息作为一个AR会话的一部分

  • ARCamera类:
    在一个AR会话中摄像机的位置和成像特征信息为捕获视频帧

  • ARLightEstimate类
    在一个AR会话中估计场景照明信息关联到一个捕获的视频帧

coreML

iOS11引入的一个全新的机器学习框架,同时伴随着Vision框架。Core ML 是特定框架功能的基础,支持用于用户图像分析的 Vision,用于自然语言处理的 Foundation (如 NSLinguisticTagger 类)和用于评估已经学习到的决策树 GamePlayKit。Core ML 本身构建于低层面的原语上,比如 Accelerate、BNNS、Metal Performance Shaders。coreML让我们更容易在App中使用训练过的模型, 而Vision让我们轻松访问苹果的模型,用于面部检测、面部特征点、文字、矩形、条形码和物体等。Vision模型中可以包装任意的图像分析coreML模型。Vision框架其实就是对coreML框架的一层封装,使用起来更加方便。根据官方文档提供的图像可以看出,这两个框架的作用,就是将一个ML模型,转换成我们的app工程可以直接使用的对象。

  • 机器学习(ML:Machine Learning):
    是一种人工智能,计算机会“学习”而不是被明确编程。不用编写算法,机器学习工具通过在大量数据中寻找模式,使计算机能够开发和优化算法。机器学习(ML)是人工智能(AI)的一个分支,深度学习(DL)又是更小分一个分支,大概关系如图所示

Demo:

  1. 建立一个工程,选择Augmented Reality App, 会帮我们创建一个ARSCNView视图

2.到官网下载一个模型 模型下载, 每个模型的作用都有对应的解释,能识别的图像种类也不尽相同,根据不同需求下载不同模型

3.将模型拖入工程中,可能需要加载一会才会显示,如下图所示。选中模型,会出现模型相关信息,大小、功能、类型等。Model Class下会有一个箭头,点击进入会看到模型的源码。Model Evaluation Parameter下会有模型的输入(input)输出(outPuts)信息。输入的需要时大小为224*224的图片,而返回的结果一个是classLabelProbs,即信任度或百分比,而classLabel即得到的结果。不同模型的输输出并不相同。注意右下角的Target Members在Xcode9中默认不会勾选,需要手动选中。

4.创建模型并声明相关变量

1
2
3
4
5
var resentModel = Resnet50()

var hitTestResult: ARHitTestResult!

var visionRequests = [VNRequest]()

5.给当前场景添加一个手势

1
2
3
4
func registerGestureRecognizers() {
let tapGesture = UITapGestureRecognizer(target:self, action:#selector(tapped))
sceneView.addGestureRecognizer(tapGesture)
}

6.点击场景

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@objc func tapped(tapGesture:UITapGestureRecognizer) {
let sceneView = tapGesture.view as! ARSCNView
let touchLocation = tapGesture.location(in: self.sceneView)
guard let currentFrame = sceneView.session.currentFrame else {
fatalError("no pixel")
}

let hitTestResults = sceneView.hitTest(touchLocation, types: .featurePoint)
if hitTestResults.isEmpty { return }
guard let hitTestResult = hitTestResults.first else {
fatalError("not first object")
}

self.hitTestResult = hitTestResult;
// image->pixel
let pixelBuffer = currentFrame.capturedImage;

// Vision
performVisonRequest(pixelBuffer: pixelBuffer)
}

7.通过Vision处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
func performVisonRequest(pixelBuffer:CVPixelBuffer) {
let visionModel = try! VNCoreMLModel(for:self.resentModel.model)
let request:VNCoreMLRequest = VNCoreMLRequest(model:visionModel) { request,error in
if error != nil { return }
guard let observations = request.results else {
fatalError("no result")
}

let observation = observations.first as! VNClassificationObservation
print("name is \(observation.identifier) \n confidence is \(observation.confidence)")

DispatchQueue.main.async {
self.displayPredictions(text: observation.identifier)
}
}
request.imageCropAndScaleOption = .centerCrop;
visionRequests = [request]
let imageRequestHandler:VNImageRequestHandler = VNImageRequestHandler(cvPixelBuffer:pixelBuffer,orientation:.upMirrored,options:[:])

DispatchQueue.global().async {
try? imageRequestHandler.perform(self.visionRequests)
}
}

8.展示预测结果

func displayPredictions(text:String) {
let parentNode = SCNNode()

    // 1cm
    let sphere = SCNSphere(radius:0.01)
    let sphereMaterial = SCNMaterial()
    sphereMaterial.diffuse.contents = UIColor.orange
    sphere.firstMaterial = sphereMaterial

    let sphereNode = SCNNode(geometry:sphere)
    parentNode.addChildNode(sphereNode)

    // text
    let textGeo = SCNText(string:text,extrusionDepth:0)
    textGeo.alignmentMode = kCAAlignmentCenter
    textGeo.firstMaterial?.diffuse.contents = UIColor.orange
    textGeo.firstMaterial?.specular.contents = UIColor.white
    textGeo.firstMaterial?.isDoubleSided = true
    textGeo.font = UIFont(name:"Futura",size:0.20)

    let textNode = SCNNode(geometry:textGeo)
    textNode.position = SCNVector3(x:self.hitTestResult.worldTransform.columns.3.x,
                                   y:self.hitTestResult.worldTransform.columns.3.y,
                                   z:self.hitTestResult.worldTransform.columns.3.z)
    textNode.scale = SCNVector3Make(0.2,0.2,0.2)
    parentNode.addChildNode(textNode)

    parentNode.position = SCNVector3(x:self.hitTestResult.worldTransform.columns.3.x,
                                     y:self.hitTestResult.worldTransform.columns.3.y,
                                     z:self.hitTestResult.worldTransform.columns.3.z)
    // show AR resutl
    self.sceneView.scene.rootNode.addChildNode(parentNode)
}

9.结果展示

运行项目,将真机对准物体,距离适中。注意苹果AR仅支持搭载A9/A10及更先进处理器的iOS 11设备,接下来新出的苹果设备,也同样会支持苹果AR功能。目前支持机型如下:

  • iPhone6s和6S Plus
  • iPhone7和7 Plu
  • iPhone SE
  • iPad Pro (9.7, 10.5和12.9)
  • iPad (2017

最终展示效果如下,结果其实可能并不准确,但是提供了一个可能性。展示结果也可以呈现多样性,比如显示百分比,显示可信度排名前几的分析对象等


Demo下载

如有任何疑问或问题请联系我:fishnewsdream@gmail.com,欢迎交流,共同提高!

Objective-C/Swift技术开发交流群201556264,讨论何种技术并不受限,欢迎各位大牛百家争鸣!

微信公众号OldDriverWeekly,欢迎关注并提出宝贵意见

老司机iOS周报,欢迎关注或订阅

刚刚在线工作室,欢迎关注或提出建设性意见!

刚刚在线论坛, 欢迎踊跃提问或解答!

如有转载,请注明出处,谢谢!

本站总访问量 本文总阅读量